<?php
namespace app\utils;
use think\facade\Cache;

class Redis
{
    protected $redis;

    /**
     * Summary of __construct
     * @param string $redisName
     */
    public function __construct(string $redisName)
    {
        $this->redis = Cache::store($redisName)->handler();
    }
    /**
     * 获取redis实例
     */
    public function getRedis()
    {
        return $this->redis;
    }
    /**
     * redis set
     * @param string $key 键名
     * @param mixed $value 值
     * @param mixed $expire 过期时间(s)
     * @return bool true|false
     */
    public function set(string $key, $value, $expire = 0)
    {
        return $this->redis->set($key, $value, $expire);
    }
    public static function setKey(string $redisName,string $key, $value, $expire = 0)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->set($key, $value, $expire);
    }
    /**
     * redis get
     * @param string $key
     */
    public function get(string $key)
    {
        return $this->redis->get($key);
    }
    public static function getKey(string $redisName,string $key)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->get($key);
    }
    /**
     * redis exists 查看符合条件所有的key
     * ? 匹配一个字符 例： user:? true: user:1 user:2 false: user:ab
     * * 匹配多个字符 例： user:* true: user:1 user:2 user:ab
     * [] [a-z]匹配a-z之间的字符 例： user:[a-z] true: user:a user:b user:c false: user:1 user:2
     * @param string $key 
     * @return array 符合的key
     */
    public function keys(string $key)
    {
        return $this->redis->keys($key);
    }

    /**
     * redis exists 查看key是否存在
     * @param string $key
     */
    public function exists(string $key)
    {
        return $this->redis->exists($key);
    }
    public static function existsKey(string $redisName,string $key)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->exists($key);
    }
    /**
     * redis expire 设置key的过期时间
     * @param string $key
     * @param int $expire 过期时间(s)
     */
    public function expire(string $key, int $expire)
    {
        return $this->redis->expire($key, $expire);
    }
    public static function expireKey(string $redisName,string $key, int $expire)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->expire($key, $expire);
    }
    /**
     * redis TTl 获取key的剩余时间
     * @param string $key
     * @param int $expire 过期时间(s)
     */
    public function ttl(string $key)
    {
        return $this->redis->ttl($key);
    }
    public static function ttlKey(string $redisName,string $key)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->ttl($key);
    }

    /**
     * redis del
     * @param string $key
     * @return number 1:成功|0：失败
     */
    public function del(string $key)
    {
        return $this->redis->del($key);
    }
    public static function delKey(string $redisName,string $key)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->del($key);
    }

    /**
     * redis Hash 设置
     * @param string $key 键名
     * @param array $value 值
     * @return number  返回 数量（新增）或 0（更新）
     */
    public function hSet(string $key, array $value)
    {
        return $this->redis->hMSet($key, $value);
    }
    public static function hSetD(string $redisName,string $key, $value)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->hSet($key, $value);
    }
    /**
     * redis Hash 获取单个字段
     * @param string $key 键名
     * @param string $field 字段名
     * @return string 字段值
     */
    public function hGet(string $key, string $field)
    {
        return $this->redis->hGet($key, $field);
    }

    /**
     * redis Hash 获取所有字段
     * @param string $key 键名
     */
    public function hGetAll(string $key)
    {
        return $this->redis->hGetAll($key);
    }
    public static function hGetAllS(string $redisName,string $key)
    {
        $redis = Cache::store($redisName)->handler();
        return $redis->hGetAll($key);
    }
    /**
     * redis Hash 判断字段是否存在
     * @param string $key 键名
     * @param string $field 字段名
     */
    public function hExists(string $key, string $field)
    {
        return $this->redis->hExists($key, $field);
    }

    /**
     * redis Hash 删除
     * @param string $key 键名
     * @param array $field 字段名
     * @return number 删除数量
     */
    public function hDel(string $key, array $field)
    {
        return $this->redis->hDel($key, ...$field);
    }

    /**
     * redis set集合 新增
     * @param string $key 键名
     * @param array $value 键名
     * @return number 返回新增元素数量（已存在的忽略）
     */
    public function sAdd(string $key, array $value)
    {
        return $this->redis->sAdd($key, ...$value);
    }

    /**
     * redis set集合 获取所有元素
     * @param string $key 键名
     */
    public function sMembers(string $key)
    {
        return $this->redis->sMembers($key);
    }

    /**
     * redis set集合 删除key中字段
     * @param string $key 键名
     * @param array $field 字段名 
     * @return number  返回 数量（新增）或 0（更新）
     */
    public function sRem(string $key, array $field)
    {
        return $this->redis->sRem($key, ...$field);
    }

    /**
     * redis set集合 查看字段是否存在
     * @param string $key 键名
     * @param string $field 字段名 
     * @return bool true|false
     */
    public function sIsMember(string $key, string $field)
    {
        return $this->redis->sIsMember($key, $field);
    }

    /**
     * redis set集合 合并输出
     * @param array $key 键名
     * @return array 返回查询所有key值的集合
     */
    public function sUnion(array $key)
    {
        return $this->redis->sUnion(...$key);
    }

    /**
     * redis List 从左侧新增
     * @param string $key 键名
     * @param array $value 键名
     * @return number 返回新增元素数量（已存在的忽略）
     */
    public function lPush(string $key, array $value)
    {
        return $this->redis->lPush($key, ...$value);
    }

    /**
     * redis List 从右侧新增
     * @param string $key 键名
     * @param array $value 键名
     * @return number 返回新增元素数量（已存在的忽略）
     */
    public function rPush(string $key, array $value)
    {
        return $this->redis->rPush($key, ...$value);
    }

    /**
     * redis List 从右侧新增
     * @param string $key 键名
     * @param string $type 插入类型，可以是before after
     * @param string $valPos 定位值
     * @param string $valInsert 插入值
     * @return number 列表长度|-1 插入失败|0 空列表
     */
    public function lInsert(string $key, string $type, string $valPos, string $valInsert)
    {
        return $this->redis->lInsert($key, $type, $valPos, $valInsert);
    }

    /**
     * redis List 查询
     * @param string $key 键名
     * @param int $start 开始位置 默认0
     * @param int $end 结束位置 默认-1
     */
    public function lRange(string $key, int $start = 0, int $end = -1)
    {
        return $this->redis->lRange($key, $start, $end);
    }

    /**
     * redis List 查询列表长度
     * @param string $key 键名
     */
    public function lLen(string $key)
    {
        return $this->redis->lLen($key);
    }

    /**
     * redis List 删除
     * @param string $key 键名
     * @param int $count 删除数量 默认0(所有) 正数删除前N个，负数删除后N个
     * @param string $value 删除值
     */
    public function lRem(string $key, int $value, int $count = 0)
    {
        return $this->redis->lRem($key, $count, $value);
    }
    /**
     * redis List 修改列表 （只保留位置内的元素）
     * @param string $key 键名
     * @param int $start 开始位置
     * @param int $end 结束位置
     */
    public function lTrim(string $key, int $start, int $end)
    {
        return $this->redis->lTrim($key, $start, $end);
    }

    /**
     * redis List 删除列表第一个元素并返回
     * @param string $key 键名
     * @return string 返回删除元素|当列表 key 不存在时，返回 nil 。
     */
    public function lPop(string $key)
    {
        return $this->redis->lPop($key);
    }

    /**
     * redis List 删除列表最后一个元素并返回
     * @param string $key 键名
     * @return string 返回删除元素|当列表 key 不存在时，返回 nil 。
     */
    public function rPop(string $key)
    {
        return $this->redis->rPop($key);
    }

    /**
     * redis sortedset(有序集合) 新增
     * @param string $key 键名
     * @param array $value 键名
     * @return number 返回新增元素数量（已存在的忽略）
     */
    public function zAdd(string $key, array $value)
    {
        $zAddArr = [];
        foreach ($value as $k => $v) {
            $zAddArr[] = $k;
            $zAddArr[] = $v;
        }
        return $this->redis->zAdd($key, ...$zAddArr);
    }

    /**
     * redis sortedset(有序集合) 按分数升序获取范围（0 到 -1 表示全部）
     * @param string $key 键名
     * @param int $start 开始位置 默认0
     * @param int $end 结束位置 默认-1
     * @param bool $withscores 是否返回分数
     */
    public function zRange(string $key, int $start = 0, int $end = -1, bool $withscores = true)
    {
        return $this->redis->zRange($key, $start, $end, ['withscores' => $withscores]);
    }

    /**
     * redis sortedset(有序集合) 按分数降序获取范围（0 到 -1 表示全部）
     * @param string $key 键名
     * @param int $start 开始位置 默认0
     * @param int $end 结束位置 默认-1
     * @param bool $withscores 是否返回分数
     */
    public function zRevRange(string $key, int $start = 0, int $end = -1, bool $withscores = true)
    {
        return $this->redis->zRevRange($key, $start, $end, ['withscores' => $withscores]);
    }
    /**
     * redis sortedset(有序集合) 根据分数区间查询
     * @param string $key 键名
     * @param int $start 开始值
     * @param int $end 结束值
     * @param bool $withscores 是否返回分数
     */
    public function zRangeByScore(string $key, int $start, int $end, bool $withscores = true)
    {
        return $this->redis->zRangeByScore($key, $start, $end, ['withscores' => $withscores]);
    }

    /**
     * redis sortedset(有序集合) 获取元素的排名（从小到大）
     * @param string $key 键名
     * @param string $value 开始位置 默认0
     */
    public function zRank(string $key, string $value)
    {
        return $this->redis->zRank($key, $value);
    }

    /**
     * redis sortedset(有序集合) 删除
     * @param string $key 键名
     * @param array $fields 值
     */
    public function zRem(string $key, array $fields)
    {
        return $this->redis->zRem($key, ...$fields);
    }

    /**
     * redis sortedset(有序集合) 按排名删除
     * @param string $key 键名
     * @param int $start 开始值
     * @param int $end 结束值
     */
    public function zRemRangeByRank(string $key, int $start, int $end)
    {
        return $this->redis->zRemRangeByRank($key, $start, $end);
    }

    /**
     * redis sortedset(有序集合) 按分数区间删除
     * @param string $key 键名
     * @param int $start 开始值
     * @param int $end 结束值
     */
    public function zRemRangeByScore(string $key, int $start, int $end)
    {
        return $this->redis->zRemRangeByScore($key, $start, $end);
    }

    /**
     * 开始事务
     */
    public  function multi()
    {
        return $this->redis->multi();
    }

    /**
     * 执行事务
     */
    public  function exec()
    {
        return $this->redis->exec();
    }

    
    /**
     * 取消事务
     */
    public  function discard()
    {
        return $this->redis->discard();
    }
}
